<template>
  <div style="width: 100%; height: 100%">
    <el-table
      :data="tableData"
      :stripe="componentProps.stripe"
      :border="componentProps.border"
      :size="componentProps.size"
      :height="componentProps.height === 'auto' ? undefined : componentProps.height"
      :max-height="componentProps.maxHeight === 'auto' ? undefined : componentProps.maxHeight"
      style="width: 100%; height: 100%"
    >
      <el-table-column
        v-for="column in componentProps.columns"
        :key="column.prop"
        :prop="column.prop"
        :label="column.label"
        :width="column.width"
        :min-width="column.minWidth"
        :align="column.align"
      />
    </el-table>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue';
import { ElTable, ElTableColumn } from 'element-plus';
import { useAutoDataBinding } from '@/composables/use-data-binding';
import { shouldUpdateChartData } from '@/utils/shallow-equal';
import type { IDataBindingConfig } from '@/components/mt-edit/store/types';

interface TableColumn {
  prop: string;
  label: string;
  width?: string | number;
  minWidth?: string | number;
  align?: 'left' | 'center' | 'right';
}

interface TableDataRow {
  [key: string]: any;
}

const props = defineProps({
  // 数据绑定配置
  dataBinding: {
    type: Object as () => IDataBindingConfig,
    default: () => ({
      enabled: false,
      sourceId: '',
      dataPointId: '',
      targetProperty: 'data',
      transform: 'array',
      defaultValue: '[]',
      updateInterval: 0,
      updateMode: 'replace',
      maxArrayItems: 100
    })
  },
  columns: {
    type: Array as () => TableColumn[],
    default: () => [
      { prop: 'name', label: '姓名', width: 120, align: 'center' },
      { prop: 'age', label: '年龄', width: 80, align: 'center' },
      { prop: 'address', label: '地址', minWidth: 200, align: 'left' }
    ]
  },
  data: {
    type: Array as () => TableDataRow[],
    default: () => [
      { name: '张三', age: 25, address: '北京市朝阳区' },
      { name: '李四', age: 30, address: '上海市浦东新区' },
      { name: '王五', age: 28, address: '广州市天河区' }
    ]
  },
  stripe: {
    type: Boolean,
    default: true
  },
  border: {
    type: Boolean,
    default: true
  },
  size: {
    type: String as () => 'large' | 'default' | 'small',
    default: 'default'
  },
  height: {
    type: [String, Number],
    default: 'auto'
  },
  maxHeight: {
    type: [String, Number],
    default: 'auto'
  }
});

// 响应式属性对象（用于数据绑定）
const componentProps = ref({
  columns: props.columns,
  data: props.data,
  stripe: props.stripe,
  border: props.border,
  size: props.size,
  height: props.height,
  maxHeight: props.maxHeight
});

// 使用数据绑定
const shouldUseDataBinding =
  props.dataBinding && props.dataBinding.enabled && props.dataBinding.targetProperty !== 'hide';
const dataBinding = useAutoDataBinding(
  shouldUseDataBinding ? props.dataBinding : null,
  componentProps.value,
  (property: string, value: any) => {
    // 直接更新响应式对象的属性
    if (componentProps.value.hasOwnProperty(property)) {
      (componentProps.value as any)[property] = value;
    }
  }
);

// 监听数据绑定的值变化
// 性能优化：使用浅比较避免不必要的重新渲染
watch(
  () => dataBinding.currentValue.value,
  (newValue, oldValue) => {
    // 如果数据绑定启用且有新值，更新组件属性
    if (shouldUseDataBinding && newValue !== undefined) {
      // 确保数据是数组格式
      let tableData = newValue;
      if (!Array.isArray(tableData)) {
        if (typeof tableData === 'string') {
          try {
            tableData = JSON.parse(tableData);
          } catch (e) {
            tableData = [];
          }
        } else if (typeof tableData === 'object' && tableData !== null) {
          // 如果是对象，转换为数组
          tableData = Object.values(tableData);
        } else {
          tableData = [];
        }
      }

      // 性能优化：使用浅比较检查数据是否真的发生变化
      if (shouldUpdateChartData(tableData, componentProps.value.data)) {
        // 数据绑定系统已经处理了更新模式，这里直接使用处理后的数据
        componentProps.value.data = tableData;
      }
    }
  },
  { immediate: true, deep: false }
);

// 监听连接状态变化
// 性能优化：添加相等性检查避免不必要的副作用
watch(
  () => dataBinding.isConnected.value,
  (newValue, oldValue) => {
    if (newValue === oldValue) return;
    // 连接状态变化的处理逻辑（如果需要）
  },
  { immediate: true }
);

// 监听props变化，同步到响应式属性对象
// 性能优化：使用浅比较检查数组数据变化
watch(
  () => props.columns,
  (newValue, oldValue) => {
    if (shouldUpdateChartData(newValue, oldValue)) {
      componentProps.value.columns = newValue;
    }
  },
  { deep: false }
);
// 性能优化：基本类型属性添加相等性检查
watch(
  () => props.stripe,
  (newValue, oldValue) => {
    if (newValue !== oldValue) {
      componentProps.value.stripe = newValue;
    }
  }
);
// 性能优化：基本类型属性添加相等性检查
watch(
  () => props.border,
  (newValue, oldValue) => {
    if (newValue !== oldValue) {
      componentProps.value.border = newValue;
    }
  }
);
// 性能优化：基本类型属性添加相等性检查
watch(
  () => props.size,
  (newValue, oldValue) => {
    if (newValue !== oldValue) {
      componentProps.value.size = newValue;
    }
  }
);
// 性能优化：基本类型属性添加相等性检查
watch(
  () => props.height,
  (newValue, oldValue) => {
    if (newValue !== oldValue) {
      componentProps.value.height = newValue;
    }
  }
);
// 性能优化：基本类型属性添加相等性检查
watch(
  () => props.maxHeight,
  (newValue, oldValue) => {
    if (newValue !== oldValue) {
      componentProps.value.maxHeight = newValue;
    }
  }
);
// 性能优化：使用浅比较检查数组数据变化
watch(
  () => props.data,
  (newValue, oldValue) => {
    if (!shouldUseDataBinding && shouldUpdateChartData(newValue, oldValue)) {
      componentProps.value.data = newValue;
    }
  },
  { deep: false }
);

// 使用计算属性来获取当前的表格数据
const tableData = computed(() => {
  if (shouldUseDataBinding && dataBinding.currentValue.value !== undefined) {
    let data = dataBinding.currentValue.value;

    // 确保数据是数组格式
    if (!Array.isArray(data)) {
      if (typeof data === 'string') {
        try {
          data = JSON.parse(data);
        } catch {
          data = [];
        }
      } else if (typeof data === 'object' && data !== null) {
        data = Object.values(data);
      } else {
        data = [];
      }
    }

    return data;
  } else {
    return componentProps.value.data;
  }
});
</script>
